#include "GameplayState.h"
#include "MainMenuState.h"
#include "Game.h"
#include "../SGD Wrappers/CSGD_Direct3D.h"
#include "../SGD Wrappers/CSGD_TextureManager.h"
#include "../SGD Wrappers/CSGD_XAudio2.h"
#include "../SGD Wrappers/CSGD_DirectInput.h"
//#include "../SGD Wrappers/SGD_Math.h"
#include <cassert>
#include "Elemental.h"
#include <string>
using namespace std;
#include "BitmapFont.h"
#include <vector>
using namespace std;
#include "../tinyxml/tinyxml.h"
#include "Elemental.h"
#include "ObjectFactory.h"
#include "ObjectManager.h"
#include "Waypoint.h"
#include "TileSystem.h"
#include "MessageSystem.h"
#include "Player.h"
#include "Message.h"
#include "CreateTowerMessage.h"
#include "Tower.h"
#include "Node.h"
#include "Map.h"
#include "DestoryElementalMessage.h"
#include "AnimationManager.h"
#include "AnimationInfo.h"
#include "MenuManager.h"
#include "PauseState.h"
#include "ParticleFactory.h"

CGameplayState* CGameplayState::GetInstance()
{
	static CGameplayState s_Instance;
	return &s_Instance;
}

CGameplayState::CGameplayState(void)
{
	m_pD3D		= nullptr;
	m_pDI		= nullptr;
	m_pTM		= nullptr;
	m_pXA		= nullptr;
	m_pTS		= nullptr;
	m_pAnimation = nullptr;
	m_pFrame = nullptr;
}

CGameplayState::~CGameplayState()
{
}

void CGameplayState::Enter( void )
{
	m_pD3D	= CSGD_Direct3D::GetInstance();
	m_pDI	= CSGD_DirectInput::GetInstance();
	m_pTM	= CSGD_TextureManager::GetInstance();
	m_pXA	= CSGD_XAudio2::GetInstance();
	m_pOF	= CObjectFactory::GetInstance();
	m_pOM	= CObjectManager::GetInstance();
	m_pMS	= CMessageSystem::GetInstance();

	m_pOF->Init();
	m_pTS = new CTileSystem;

Map pTempMap;	// Animation System****************************************
	m_pAnimationManager = CAnimationManager::GetInstance();
	m_pAnimationManager->Load( "testfile.xml" );
	m_pAnimationInfo = new CAnimationInfo();
	m_pAnimationInfo->SetCurrentAnimation( "PC_PlayerWalkLeft" );
	m_pAnimationInfo->SetRefCount( 0 );	m_pMS->InitMessageSystem( &MessageProc );
	m_vLanes.clear();
	pTempMap.LoadMap("Resources/Definitions/boop.xml", m_vLanes, m_pTS);
	for( int i = 0; i < m_vLanes.size(); i++ )
		m_vElementalsInALane.resize(3);
	Player1 = new CPlayer;
	Player1->SetPlayer(true);
	Player2 = new CPlayer;
	Player2->SetPlayer(false);

	//m_pAnimationInfo->AddRef();

	ParticleFactory::GetInstance()->Enter();
	emitter = ParticleFactory::GetInstance()->CreateEmitter("flamethrower");
	emitter.Init();}

void CGameplayState::Exit()
{
	emitter.Exit();
	ParticleFactory::GetInstance()->Exit();

	m_pTM->UnloadTexture(m_pTS->GetImageID());
	delete m_pTS;
	m_pOM->RemoveAllObjects();
	m_pOM->DeleteInstance();
	m_pMS->ShutdownMessageSystem();
	m_pOF->ShutDown();
	delete Player1;
	delete Player2;

	//**** ANIMATION INFO
	delete m_pAnimationInfo;
	m_pAnimationManager->Shutdown();
}

bool CGameplayState::Input()
{
	Player1->Input();
	Player2->Input();

	if( m_pDI->KeyPressed( DIK_ESCAPE ))
	{
		CMenuManager::GetInstance()->GoBack();
		CGame::GetInstance()->ChangeState( CMenuManager::GetInstance()->PlayBack() );
		//return false;
	}

	if( m_pDI->KeyPressed( DIK_RETURN ))
	{
		CMenuManager::GetInstance()->AddMenu(CPauseState::GetInstance());
		CPauseState::GetInstance()->Enter();
		//CGame::GetInstance()->ChangeState( CMenuManager::GetInstance()->PlayBack() );
		//return false;
	}

	return true;
}

void CGameplayState::Update(float fElapsedTime)
{
	m_pOM->UpdateAllObjects(fElapsedTime);
	m_pOM->CheckCollisions();

	m_pMS->ProcessMessages();

	Player1->Update(fElapsedTime);
	Player2->Update(fElapsedTime);
	emitter.Update(fElapsedTime);

}

void CGameplayState::Render()
{
	m_pTS->Render();
	m_pOM->GetInstance()->RenderAllObjects();

	emitter.Render();

	 //What is this????
	for( int i = 0; i < 5; i++ )
	{
		char number [5];
		//_itoa_s(Player1->GetSingleMoney(i),number,5);
		sprintf_s(number,"%i",Player1->GetSingleMoney(i));
		m_pD3D->DrawText(number,0+(i*20),0);
	}
}

void CGameplayState::MessageProc( IMessage* pMsg )
{
	CGameplayState* self = CGameplayState::GetInstance();

	// What type of message?
	switch( pMsg->GetMessageID() )
	{
	case Msg_SpawnTower:
		  {
			CCreateTowerMessage* newMsg = dynamic_cast<CCreateTowerMessage*>(pMsg);
			CObjectFactory::GetInstance()->SpawnTower(newMsg->GetType(), newMsg->GetPosX(), newMsg->GetPosY(),0);
			break;
		  }
	case Msg_DestroyElemental:
		{
			CDestoryElementalMessage* pDestroyMsg = dynamic_cast<CDestoryElementalMessage*>(pMsg);
			self->m_pOM->RemoveObject(pDestroyMsg->GetUnit());
		}
	}
}

vector<CWaypoint*> CGameplayState::LanePath( short laneNumber )
{
	return m_vLanes[laneNumber];
}

vector<CElemental*> CGameplayState::GetElementalLane( short index )
{
	return m_vElementalsInALane[index];
}

void CGameplayState::AddElementalToLane( CElemental* goon, short laneNum )
{
	m_vElementalsInALane[laneNum].push_back(goon);
}

CEntity* CGameplayState::CheckForTargets( CEntity* CheckThis )
{

	switch( CheckThis->GetType() )
	{
	case CEntity::Obj_Elemental:
			{
				vector<CElemental*> tempVector;
				tempVector = GetElementalLane(dynamic_cast<CElemental*>(CheckThis)->GetLane());
				for( vector<CElemental*>::iterator iter = tempVector.begin(); iter != tempVector.end(); iter++ )
				{
					if( *iter == CheckThis )
						continue;
				}
			}
	case CEntity::Obj_Tower:
			{
				return CheckThis;
			}
	}
}
